#pragma once
#include <windows.h>
#include <wincrypt.h>
#include <vcclr.h>
#using <system.dll>
#using <system.security.dll>

namespace Safe
{
	/// Provides a managed wrapper class around the CRYPT_DER_BLOB structure
	public ref class ManagedCryptBlob {

		public:
			/// Gets/sets the data buffer
			property array<unsigned char>^ Data;
			/// Gets the length of the data in the buffer
			property int Length { 
				int get() { return Data->Length; }
			}

		public:
			/// <summary>
			/// Creates a new ManagedCryptBlob by copying the data from a 
			/// CRYPT_DER_BLOB
			/// </summary>
			/// <param name='pBlob'>The source of the data</param>
			ManagedCryptBlob(CRYPT_DER_BLOB &pBlob);

			/// <summary>
			/// Creates a new ManagedCryptBlob by copying the passed-in data
			/// </summary>
			/// <param name='pbData'>The source buffer</param>
			/// <param name='cbData'>The length of the source buffer</param>
			ManagedCryptBlob(BYTE *pbData, DWORD cbData);

			/// <summary>
			/// Creates a new ManagedCryptBlob by copying the passed-in data
			/// </summary>
			/// <param name='arrData'>The source buffer</param>
			ManagedCryptBlob(array<unsigned char>^ arrData);

			/// <summary>
			/// Destructor
			/// <summary>
			virtual ~ManagedCryptBlob();

			/// <summary>
			/// Copies the data from the ManagedCryptBlob into a CRYPT_DER_BLOB.  To get 
			/// the length of the buffer needed to hold the data, either use the 
			/// Length property of the object, or call this function with a CRYPT_DER_BLOB
			/// that has NULL for the pbData member.  This will populate the cbData member
			/// with the required length.
			/// This function does not perform allocation, so the calling function is
			/// responsible for both allocating and freeing the CRYPT_DER_BLOB's pbData buffer.
			/// </summary>
			/// <param name='blob'>The destination blob</param>
			/// <returns>true if the copy function succeeded, false if not.  The operation will
			/// only fail if the CRYPT_DER_BLOB does not contain enough bytes for all of the
			/// data</returns>
			bool CreateBlob(CRYPT_DER_BLOB &blob);

			/// <summary>
			/// Determines if this object is equivalent to another ManagedCryptBlob.  If
			/// the lengths of the buffers differ, or if any of the data within the buffers
			/// differ, the function returns false.  Otherwise, the objects are
			/// considered equal.
			/// </summary>
			/// <param name='obj'>The ManagedCryptBlob to compare against this</param>
			/// <returns>true if this and obj have the same length, and the data in the
			/// buffers are identical</returns>
			bool Equals( ManagedCryptBlob^ obj );
	};
}